<template>
  <div ref="wrapRef" v-if="fileList && fileList.length" class="upload-preview">
    <div
      v-for="(item, index) of fileList"
      :key="item.uid || index"
      class="upload-preview-item"
      :class="`upload-preview-item-${item.status}`"
    >
      <div class="upload-preview-item-wrap">
        <img
          v-if="item && item.url && isImage(item)"
          :src="item.url"
          class="upload-preview-item-image"
          alt="image"
          @click.stop.prevent="handlePreview(item)"
        />
        <div v-else class="upload-preview-item-file">
          <img v-if="getFileIcon(item)" :src="getFileIcon(item)" />
          <FileOutlined v-else :style="{ fontSize: iconFont || '60px' }" />
        </div>
        <div class="upload-preview-item-text" :title="item.name">{{ item.name }}</div>
        <div class="upload-preview-item-del" @click="handleRemove(index)">×</div>
        <div
          class="upload-preview-item-mask"
          v-if="0 < item.progress && item.progress < 100"
          :style="{ width: (item.progress || 0) + '%' }"
        ></div>
      </div>
    </div>
  </div>
</template>

<script>
import { FileOutlined } from '@ant-design/icons-vue';

import { handlePreview, isImage, getFileIcon } from './uploadUtils.js';

export default {
  name: 'UploadPreview',
  components: { FileOutlined },
  props: {
    fileList: Array,
    column: Number,
    iconSize: [String, Number],
  },
  computed: {
    width() {
      const col = this.column;
      return 100 / (Number.isFinite(col) ? col : 4) + '%';
    },
    iconFont() {
      const size = this.iconSize;
      return typeof size === 'number' ? size + 'px' : size;
    },
  },
  methods: {
    isImage,
    getFileIcon,
    handlePreview,
    handleRemove(index) {
      if (typeof this.$attrs.onRemove === 'function') {
        return this.$attrs.onRemove(index);
      }
      const list = this.fileList.slice(0);
      list.splice(index, 1);
      this.$emit('update:fileList', list);
    },
  },
};
</script>

<style scoped lang="less">
.upload-preview {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: flex-start;
  width: 100%;
  .upload-preview-item {
    position: relative;
    box-sizing: border-box;
    display: block;
    width: v-bind(width);
    height: 0;
    margin: 0;
    border: none;
    padding: 0 0 v-bind(width);
    color: #999999;
    &.upload-preview-item-waiting {
      color: #999999;
    }
    &.upload-preview-item-done {
      color: #54d016;
    }
    &.upload-preview-item-fail {
      color: #ff4d4f;
    }
    .upload-preview-item-wrap {
      position: absolute;
      top: 0.25em;
      right: 0.25em;
      bottom: 0.25em;
      left: 0.25em;
      margin: 0;
      padding: 0.25em;
      border: 2px solid currentColor;
      border-radius: 4px;
      font-size: 14px;

      .upload-preview-item-image {
        position: absolute;
        z-index: 1;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        user-select: none;
      }
      .upload-preview-item-file {
        position: absolute;
        z-index: 1;
        top: 0.5em;
        left: 0;
        display: flex;
        justify-content: center;
        align-items: flex-start;
        width: 100%;
        cursor: pointer;
        font-size: inherit;
        user-select: none;
      }
      .upload-preview-item-text {
        position: absolute;
        z-index: 2;
        bottom: 0.2em;
        left: 0.5em;
        right: 0.5em;
        line-height: 1.1;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        text-align: center;
        font-size: 12px;
      }
      .upload-preview-item-del {
        position: absolute;
        z-index: 3;
        top: 0.25em;
        right: 0;
        line-height: 0.5;
        cursor: pointer;
        font-size: 18px;
        user-select: none;
      }
      .upload-preview-item-mask {
        position: absolute;
        z-index: 4;
        left: 0;
        top: 0;
        bottom: 0;
        width: 0;
        background: rgba(60, 160, 16, 0.5);
        transition: width ease 0.3s;
      }
    }
  }
}
</style>
